﻿using SharpML.Api.Annotations;
using SharpML.Api.Extensions;
using SharpML.Api.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace SharpML.Api.Implementation
{
    public sealed class PluginInstance
    {
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="path"></param>
        public PluginInstance( string path )
        {
            Assembly = Assembly.LoadFile( path );

            var descriptionAttribute = Assembly.GetCustomAttributes( typeof( AssemblyDescriptionAttribute ), false ).Cast<AssemblyDescriptionAttribute>().SingleOrDefault();

            Name = descriptionAttribute != null ? descriptionAttribute.Description : Assembly.GetName().Name;
        }

        /// <summary>
        /// Stores a reference to the plugin assembly
        /// </summary>
        public Assembly Assembly { get; private set; }

        /// <summary>
        /// The plugin's friendly name
        /// </summary>
        public string Name { get; private set; }


        /// <summary>
        /// Retrieves the component types contained within the loaded plugin
        /// </summary>
        public IEnumerable<Type> ComponentTypes
        {
            get
            {
                // Sanity check
                if( Assembly == null )
                    return new Type[] { };

                return Assembly.Discover( typeof( IPluginComponent ) ).Where( componentType => !componentType.HasAnnotation( typeof( AbstractPluginComponent ) ) );
            }
        }
    }
}
